package com.xhu.collegestudentrentalsystem.module.user.controller;
import cn.hutool.json.JSONUtil;
import com.xhu.collegestudentrentalsystem.annocation.LoginRequired;
import com.xhu.collegestudentrentalsystem.module.user.entity.House;
import com.xhu.collegestudentrentalsystem.module.user.entity.Page;
import com.xhu.collegestudentrentalsystem.module.user.entity.UserMark;
import com.xhu.collegestudentrentalsystem.module.user.entity.dto.HouseDTO;
import com.xhu.collegestudentrentalsystem.module.user.service.impl.HouseServiceImpl;
import com.xhu.collegestudentrentalsystem.module.user.service.impl.MarkServiceImpl;
import com.xhu.collegestudentrentalsystem.util.*;
import com.xhu.collegestudentrentalsystem.util.constant.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * @author zhu huilin
 * @date 2023/3/5 14:50
 */
@Controller
public class HouseController {

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private HouseServiceImpl houseService;

    @Autowired
    private MarkServiceImpl markService;

    /**
     * 房东发布房源信息
     */
    @LoginRequired
    @RequestMapping(value = "/addHouse", method = RequestMethod.POST)
    public String addHouse(@RequestParam("file")MultipartFile[] file, House house, Model model){
        // 1. 检测传输数据是否完整
        if(CheckUtils.hasEmpty(house.getCertificateNo(), house.getMonthRent(), house.getTitle(), house.getAddress(), house.getLongitudeLatitude(), house.getArea(), house.getDirection(), house.getContactName(), house.getContactPhone())){
            model.addAttribute(KeyMsg.house.ADD_HOUSE_RESULT, PointMsg.house.UN_COMPLETE_INFO);
            return "site/house-add";
        }

        // 2. 检查用户上传的房产证号是否有重复
        Boolean houseExist = houseService.isHouseExist(house.getCertificateNo());
        if(houseExist){
            model.addAttribute(KeyMsg.house.ADD_HOUSE_RESULT, PointMsg.house.REPEAT_HOUSE_CARD);
            return "site/house-add";
        }

        // 3. 文件上传，并获取到所有文件名（JSON格式）插入数据库
        String realPath = this.getClass().getResource("/").getPath() + EnumProperty.fileUpload.HOUSE_SLIDE_URL;
        System.out.println(realPath);
        try {
            String filenames = FileUtils.uploadFile(file, realPath);
            // 将第一张图设置为该房子的缩略图
            List<String> list = JSONUtil.toList(filenames, String.class);
            if(!list.isEmpty()){
                house.setSlideUrl(filenames);
                house.setThumbnailUrl(list.get(0));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 4. 填充部分初始数据
        house.setCreateTime(new Date());
        house.setUserId(hostHolder.getUser().getId());
        house.setStatus(-2);    // -2表示待审核

        // 5. 插入数据到数据库
        Long aLong = houseService.addHouse(house);
        if(aLong > 0){
            model.addAttribute(KeyMsg.house.ADD_HOUSE_RESULT, PointMsg.house.ADD_SUCCESS);
        }else {
            model.addAttribute(KeyMsg.house.ADD_HOUSE_RESULT, PointMsg.house.ADD_FAIL);
        }
        return "site/house-add";
    }

    /**
     * 房东查询自己发布的房子信息
     */
    @LoginRequired
    @RequestMapping(value = "/myAddHouse", method = RequestMethod.GET)
    public String myAddHouse(Page page, Model model){
        // 分页信息
        page.setLimit(6);

        List<House> houses = houseService.findHousesByUserId(hostHolder.getUser().getId(), page);
        page.setPath("/myAddHouse");

        if(houses.isEmpty()){
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_FAIL);
            model.addAttribute(KeyMsg.MSG, PointMsg.house.NOT_FOUND);
        }else {
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_SUCCESS);
            model.addAttribute(KeyMsg.house.HOUSE_LIST, houses);
        }
        return "site/owner-house";
    }

    /**
     * 跳转修改房子信息页面
     */
    @LoginRequired
    @RequestMapping("/turnUpdateInfoPage")
    public String updateMyHouseInfo(Long houseId, Model model){
        if(houseId != null){
            House house = houseService.findHouseById(houseId);
            if(house == null){
                return "error/404";
            }
            model.addAttribute(KeyMsg.CODE, ResultData.DATA_EXIST);
            model.addAttribute(KeyMsg.house.HOUSE_ENTITY, house);
            return "site/house-update";
        }else {
            model.addAttribute(KeyMsg.CODE, ResultData.DATA_UNEXIST);
            model.addAttribute(KeyMsg.MSG, PointMsg.error.ERROR);
            return "site/owner-house";
        }
    }

    /**
     * 修改房子信息
     */
    @LoginRequired
    @RequestMapping("/updateHouseInfo")
    public String updateHouseInfo(@RequestParam("file")MultipartFile[] file, House house, Model model){
        // 1. 检测传输数据是否完整
        if(CheckUtils.hasEmpty(house.getCertificateNo(), house.getMonthRent(), house.getTitle(), house.getAddress(), house.getLongitudeLatitude(), house.getArea(), house.getDirection(), house.getContactName(), house.getContactPhone())){
            model.addAttribute(KeyMsg.house.ADD_HOUSE_RESULT, PointMsg.house.UN_COMPLETE_INFO);
            return "site/house-add";
        }

        // 如果传输图片为空，就不修改图片信息
        String realPath = this.getClass().getResource("/").getPath() + EnumProperty.fileUpload.HOUSE_SLIDE_URL;
        try {
            String filenames = FileUtils.uploadFile(file, realPath);
            // 将第一张图设置为该房子的缩略图
            List<String> list = JSONUtil.toList(filenames, String.class);
            if(!list.isEmpty()){
                house.setSlideUrl(filenames);
                house.setThumbnailUrl(list.get(0));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        Integer result = houseService.updateHouseInfo(house);
        if(result > 0){
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_SUCCESS);
            model.addAttribute(KeyMsg.MSG, PointMsg.modify.MODIFY_SUCCESS);
        }else {
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_FAIL);
            model.addAttribute(KeyMsg.MSG, PointMsg.modify.MODIFY_FAIL);
        }
        return "site/house-update";
    }

    /**
     * 下架房子功能
     */
    @LoginRequired
    @RequestMapping("/downHouse")
    public String downHouse(Page page, Long houseId, Model model){
        // 查询是否有该房子信息
        House house = houseService.findHouseById(houseId);
        if(house == null){
            model.addAttribute(KeyMsg.ERROR_MSG, PointMsg.house.HOUSE_INFO_NOT_FOUND);
            return "error/500";
        }

        if(house.getUserId() != hostHolder.getUser().getId()){
            model.addAttribute(KeyMsg.ERROR_MSG, PointMsg.house.NO_PERMISSION);
            return "error/403";
        }

        if(house.getStatus() == StatusMsg.houseStatus.HAS_RENT){
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_FAIL);
            model.addAttribute(KeyMsg.MSG, PointMsg.house.HOUSE_HAS_RENT);
            return myAddHouse(page, model);
        }

        // 修改房子状态为下架状态
        Integer result = houseService.updateHouseStatus(houseId, StatusMsg.houseStatus.HAS_DOWN);
        if(result > 0){
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_SUCCESS);
            model.addAttribute(KeyMsg.MSG, PointMsg.house.DOWN_SUCCESS);
        }else {
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_FAIL);
            model.addAttribute(KeyMsg.MSG, PointMsg.house.DOWN_FAIL);
        }
        return myAddHouse(page, model);
    }

    /**
     * 上架房子功能
     */
    @LoginRequired
    @RequestMapping("/upHouse")
    public String upHouse(Page page, Long houseId, Model model){
        // 查询是否有该房子信息
        House house = houseService.findHouseById(houseId);
        if(house == null){
            model.addAttribute(KeyMsg.ERROR_MSG, PointMsg.house.HOUSE_INFO_NOT_FOUND);
            return "error/500";
        }

        if(house.getUserId() != hostHolder.getUser().getId()){
            model.addAttribute(KeyMsg.ERROR_MSG, PointMsg.house.NO_PERMISSION);
            return "error/403";
        }

        // 修改房子状态为待审核状态
        Integer result = houseService.updateHouseStatus(houseId, StatusMsg.houseStatus.WAIT_PASS);
        if(result > 0){
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_SUCCESS);
            model.addAttribute(KeyMsg.MSG, PointMsg.house.UP_SUCCESS);
        }else {
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_FAIL);
            model.addAttribute(KeyMsg.MSG, PointMsg.house.UP_FAIL);
        }
        return myAddHouse(page, model);
    }

    /**
     * 房东删除自己的房子信息
     */
    @LoginRequired
    @RequestMapping("/deleteHouse")
    public String deleteHouse(Long houseId, Page page, Model model){
        // 查询是否有该房子信息
        House house = houseService.findHouseById(houseId);
        if(house == null){
            model.addAttribute(KeyMsg.ERROR_MSG, PointMsg.house.HOUSE_INFO_NOT_FOUND);
            return "error/500";
        }

        if(house.getUserId() != hostHolder.getUser().getId()){
            model.addAttribute(KeyMsg.ERROR_MSG, PointMsg.house.NO_PERMISSION);
            return "error/403";
        }

        if(house.getStatus() == StatusMsg.houseStatus.HAS_RENT){
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_FAIL);
            model.addAttribute(KeyMsg.MSG, PointMsg.house.HOUSE_HAS_RENT);
            return myAddHouse(page, model);
        }

        Integer result = houseService.updateHouseStatus(houseId, StatusMsg.houseStatus.OWNER_DELETE);
        if(result > 0){
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_SUCCESS);
            model.addAttribute(KeyMsg.MSG, PointMsg.delete.DELETE_SUCCESS);
        }else {
            model.addAttribute(KeyMsg.CODE, ResultData.OPERATION_FAIL);
            model.addAttribute(KeyMsg.MSG, PointMsg.delete.DELETE_FAIL);
        }
        return myAddHouse(page, model);
    }

    /**
     * 房子详情查看
     */
    @RequestMapping("/houseDetail/{id}")
    public String houseDetail(@PathVariable("id") Long houseId, Model model){
        // 按照id查询房子信息
        House house = houseService.findHouseById(houseId);
        if(house == null){
            return "site/404";
        }
        // 处理轮播图片信息
        List<String> slideUrls = JSONUtil.toList(house.getSlideUrl(), String.class);
        house.setSlideImgList(slideUrls);

        /*
            如果是合租，查询有多少人已经租房（房子订单表）
            如果是整租，查询是否已租出去
         */
        Integer count = houseService.findHouseOrderUserCount(houseId);
        house.setHasRentRoom(count);

        // 查询当前用户是否收藏了房子信息
        if(hostHolder.getUser() != null){
            UserMark mark = markService.findUserMarkById(houseId, hostHolder.getUser().getId());
            if(mark != null){
                house.setIsMarked(true);
            }
        }

        model.addAttribute(KeyMsg.house.HOUSE_ENTITY, house);
        return "site/house-detail";
    }

    /**
     * 转向地图页面，显示地址在百度地图上的位置
     */
    @RequestMapping("/houseMap")
    public String houseMap(@RequestParam("houseId") Long houseId, Model model){
        // 按照id查询房子信息
        House house = houseService.findHouseById(houseId);
        if(house == null){
            return "site/404";
        }
        // 得到经纬度信息
        String longitudeLatitude = house.getLongitudeLatitude();
        String[] strs = longitudeLatitude.split(EnumProperty.COMMA);
        model.addAttribute(KeyMsg.address.LONGITUDE, strs[0]);
        model.addAttribute(KeyMsg.address.LATITUDE, strs[1]);
        model.addAttribute(KeyMsg.address.ADDRESS, house.getAddress());
        return "site/house-map";
    }

    /**
     * 查询房子信息
     */
    @RequestMapping("/searchHouses")
    public String searchHouses(HouseDTO houseDTO, Page page, Model model){
        page.setLimit(4);
        if(houseDTO.getOrderType() == null){
            houseDTO.setOrderType("score");
        }
        if(houseDTO.getPriceRange() != null && !EnumProperty.EMPTY_STRING.equals(houseDTO.getPriceRange())){
            String[] price = houseDTO.getPriceRange().split(EnumProperty.SEMICOLON);
            houseDTO.setMinPrice(Integer.parseInt(price[0]));
            houseDTO.setMaxPrice(Integer.parseInt(price[1]));
        }
        if(houseDTO.getAreaRange() != null && !EnumProperty.EMPTY_STRING.equals(houseDTO.getAreaRange())){
            String[] area = houseDTO.getAreaRange().split(EnumProperty.SEMICOLON);
            houseDTO.setMinArea(Integer.parseInt(area[0]));
            houseDTO.setMaxArea(Integer.parseInt(area[1]));
        }
        List<House> houses = houseService.searchHouses(houseDTO, page);
        // 房子收藏情况
        for(House house: houses) {
            if (hostHolder.getUser() != null) {
                UserMark mark = markService.findUserMarkById(house.getId(), hostHolder.getUser().getId());
                if(mark != null){
                    house.setIsMarked(true);
                }else {
                    house.setIsMarked(false);
                }
            }else {
                house.setIsMarked(false);
            }
        }
        // 如果dto为空（从导航栏获取到查询整租、合租信息）封装其他信息作为分页查询附带的条件
        houseDTO = getSearchHouseDTO(houseDTO);
        page.setPath("/searchHouses?city="+ houseDTO.getCity()
                + "&rentType=" + houseDTO.getRentType()
                + "&address=" + houseDTO.getAddress()
                + "&priceRange=" + houseDTO.getPriceRange()
                + "&areaRange=" + houseDTO.getAreaRange()
                + "&orderType=" + houseDTO.getOrderType());

        model.addAttribute(KeyMsg.house.HOUSE_LIST, houses);
        model.addAttribute(KeyMsg.house.HOUSE_DTO, houseDTO);
        return "site/house-list";
    }


    /**
     * 封装分页查询的dto信息
     * 如果部分条件为空，则封装一个对应的houseDTO查询信息
     */
    private HouseDTO getSearchHouseDTO(HouseDTO houseDTO){
        if(houseDTO.getPriceRange() == null || EnumProperty.EMPTY_STRING.equals(houseDTO.getPriceRange())){
            houseDTO.setPriceRange("0;20000");
        }
        if(houseDTO.getAreaRange() == null || EnumProperty.EMPTY_STRING.equals(houseDTO.getPriceRange())){
            houseDTO.setAreaRange("0;300");
        }
        if(houseDTO.getCity() == null){
            houseDTO.setCity("");
        }
        if(houseDTO.getAddress() == null){
            houseDTO.setAddress("");
        }
        if(houseDTO.getRentType() == null){
            houseDTO.setRentType("none");
        }
        return houseDTO;
    }

}
